package com.atguigu.gulimall.product.service.impl;

import org.springframework.stereotype.Service;

import java.util.*;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;

import com.atguigu.gulimall.product.dao.CategoryDao;
import com.atguigu.gulimall.product.entity.CategoryEntity;
import com.atguigu.gulimall.product.service.CategoryService;




@Service("categoryService")
public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity> implements CategoryService {

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<CategoryEntity> page = this.page(
                new Query<CategoryEntity>().getPage(params),
                new QueryWrapper<CategoryEntity>()
        );

        return new PageUtils(page);
    }

    // 将分类数据转换为树形结构
    @Override
    public List<CategoryEntity> listWithTree() {
        // 1. 查询所有分类（扁平列表）
        List<CategoryEntity> categoryEntities = baseMapper.selectList(null);
        if (categoryEntities == null || categoryEntities.isEmpty()) {
            return Collections.emptyList();
        }

        // 2. 初始化 children（防止 null）并建立 id -> node 映射，便于快速查找父节点
        Map<Long, CategoryEntity> idMap = new HashMap<>(categoryEntities.size());
        for (CategoryEntity c : categoryEntities) {
            // 确保 children 不为 null，后面直接添加子节点
            c.setChildren(new ArrayList<>());
            idMap.put(c.getCatId(), c);
        }

        // 3. 挂载子节点，收集根节点
        List<CategoryEntity> roots = new ArrayList<>();
        for (CategoryEntity c : categoryEntities) {
            Long parentId = c.getParentCid();
            // 判定为根节点的条件：parent 为 null / 0 或 父节点在 map 中不存在
            if (parentId == 0L || !idMap.containsKey(parentId)) {
                roots.add(c);
            } else {
                CategoryEntity parent = idMap.get(parentId);
                // parent 不为 null（因为 map.containsKey 已判断），直接加入其 children
                parent.getChildren().add(c);
            }
        }

        // 4. 对树进行递归排序，同层按 sort 升序（null 视为 0）；同时做简单的环检测
        Comparator<CategoryEntity> sortComparator
                = Comparator.comparingInt(n -> n.getSort() == null ? 0 : n.getSort());
        sortChildrenRecursively(roots, sortComparator, new HashSet<>(), 0);

        return roots;
    }

    @Override
    public void removeMenuByIds(List<Long> list) {
        int i = baseMapper.deleteBatchIds(list);
        if(i <= 0){
            log.error("删除失败");
        }
    }

    /**
     * 递归对每个节点的 children 列表排序，并对子节点继续递归。
     *
     * @param nodes 当前层节点列表
     * @param cmp 排序比较器（按 sort 升序）
     * @param visited 已访问节点 id 集合（用于检测环，避免无限递归）
     * @param depth 当前递归深度（用于保护，防止过深）
     */
    private void sortChildrenRecursively(List<CategoryEntity> nodes,
                                         Comparator<CategoryEntity> cmp,
                                         Set<Long> visited,
                                         int depth) {
        if (nodes == null || nodes.isEmpty()) return;

        // 深度保护（可根据需要调整或移除）
        if (depth > 1000) return;

        // 当前层排序
        nodes.sort(cmp);

        // 遍历每个节点，递归处理子节点
        for (CategoryEntity node : nodes) {
            Long id = node.getCatId();
            // 如果已经访问过，说明可能有环，跳过以防无限循环
            if (visited.contains(id)) {
                continue;
            }
            visited.add(id);

            // 得到 children，递归排序
            List<CategoryEntity> children = node.getChildren();
            if (children != null && !children.isEmpty()) {
                sortChildrenRecursively(children, cmp, visited, depth + 1);
            }
        }
    }


}